package com.example.micro.netty.server.thread.pool;

import java.util.concurrent.*;

public class TraceThreadPoolExecutor extends ThreadPoolExecutor {

    public TraceThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
    }

    @Override
    public void execute(Runnable task) {
        super.execute(
                wrap(task, clientTrace(Thread.currentThread().getName())));
    }

    @Override
    public Future<?> submit(Runnable task) {
        return super.submit(
                wrap(task, clientTrace(Thread.currentThread().getName())));
    }

    private Exception clientTrace(String threadName) {
        return new Exception(threadName + ": Cient stack trace");
    }

    private Runnable wrap(final Runnable task, final Exception clientStack) {
        return () -> {
            try {
                task.run();
            } catch (Exception e) {
                clientStack.printStackTrace();
                throw e;
            }
        };
    }

    public static void main(String[] args) {
        TraceThreadPoolExecutor traceThreadPoolExecutor =
                new TraceThreadPoolExecutor(0, 20, 0L,
                        TimeUnit.SECONDS, new SynchronousQueue<>());

        for (int i = 0; i < 5; i++) {
            traceThreadPoolExecutor.execute(new DivTask(100, i));
        }
    }
}
